package com.xy.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xy.dto.CertificateTempDTO;
import com.xy.dto.ExhibitionUserDTO;
import com.xy.entity.CertificateTempEntity;
import com.xy.entity.CertificateTypeEntity;
import com.xy.excel.ExhibitionUserExcel;
import com.xy.service.ExhibitionUserService;
import com.xy.service.ICertificateTempService;
import com.xy.service.ICertificateTypeService;
import com.xy.wrapper.CertificateTypeWrapper;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.DictCache;
import org.springblade.system.cache.ParamCache;
import org.springblade.system.cache.SysCache;
import org.springblade.system.cache.UserCache;
import org.springblade.system.entity.Dict;
import org.springblade.system.entity.User;
import org.springblade.system.feign.IUserClient;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author guojian
 */
@Service
@AllArgsConstructor
@Slf4j
public class ExhibitionUserServiceImpl implements ExhibitionUserService {

	private final IUserClient userClient;
	private final ICertificateTempService tempService;
	private final ICertificateTypeService typeService;

	@Override
	public Boolean save(ExhibitionUserDTO exhibitionUser) {
		//绑定证件
		List<CertificateTempDTO> tempDList = exhibitionUser.getCertificateTempDList();
		//用户
		BladeUser bladeUser = AuthUtil.getUser();
		User user = BeanUtil.copy(exhibitionUser, User.class);
		user.setTenantId(bladeUser.getTenantId());
		user.setDeptId(exhibitionUser.getDeptId());
		List<String> strings = Func.toStrList(exhibitionUser.getBizCodes());
		if (Func.isNotEmpty(strings)) {
			String roleName = ParamCache.getValue("exhibitionUser" + strings.get(0));
			if (Func.isNotEmpty(roleName)) {
				user.setRoleId(SysCache.getRoleIds(bladeUser.getTenantId(), roleName));
			}
		}
		user.setUserType(1);
		user.setRealName(exhibitionUser.getCompany());
		R<Boolean> result = userClient.saveUser(user);
		if (!result.isSuccess()) {
			throw new ServiceException(result.getMsg());
		}
		R<User> userR = userClient.userByAccount(bladeUser.getTenantId(), user.getAccount());
		if (!userR.isSuccess()) {
			throw new ServiceException(userR.getMsg());
		}
		List<CertificateTempEntity> entityList = tempDList.stream().map(o -> {
			BeanUtil.copy(o, CertificateTempEntity.class);
			o.setRealName(user.getRealName());
			o.setUserId(userR.getData().getId());
			o.setCreateDept(Long.parseLong(exhibitionUser.getDeptId()));
			return o;
		}).collect(Collectors.toList());
		return tempService.saveBatch(entityList);
	}

	@Override
	public Boolean update(ExhibitionUserDTO exhibitionUser) {
		User user = UserCache.getUser(Func.toLong(exhibitionUser.getId()));
		tempService.remove(Wrappers.<CertificateTempEntity>query().lambda().eq(CertificateTempEntity::getUserId, exhibitionUser.getId()));
		List<CertificateTempDTO> tempDList = exhibitionUser.getCertificateTempDList();
		List<CertificateTempEntity> entityList = tempDList.stream().map(o -> {
			BeanUtil.copy(o, CertificateTempEntity.class);
			o.setUserId(Long.valueOf(exhibitionUser.getId()));
			o.setRealName(user.getRealName());
			o.setCreateDept(Long.parseLong(exhibitionUser.getDeptId()));
			return o;
		}).collect(Collectors.toList());
		return tempService.saveBatch(entityList);
	}

	@Override
	public void importPeData(List<ExhibitionUserExcel> data, Boolean isCovered, String type) {
		BladeUser bladeUser = AuthUtil.getUser();
		List<CertificateTempEntity> saveList = new ArrayList<>();
		Map<String, List<ExhibitionUserExcel>> stringListMap = data.stream().collect(Collectors.groupingBy(o -> o.getAccount() + ":"+o.getCertificateType()));
		stringListMap.entrySet().stream().forEach(o->{
			List<ExhibitionUserExcel> excelList = o.getValue();
			if(excelList.size()>1){
				throw new ServiceException("一个手机号对应了多个同证件类型、请检查文件:"+o.getKey());
			}
		});

		Map<String, CertificateTypeEntity> hsamap = new HashMap<>();
		for(int i = 0;i <data.size();i++ ){
			ExhibitionUserExcel userExcel = data.get(i);
			if(hsamap.containsKey(userExcel.getCertificateType())){
				continue;
			}
			CertificateTypeEntity certificateType = typeService.getOne(Wrappers.<CertificateTypeEntity>query().lambda().eq(CertificateTypeEntity::getTypeName, userExcel.getCertificateType()));
			if (Func.isEmpty(certificateType)) {
				throw new ServiceException("第"+(i+2)+"行："+"证件类型系统不存在、请检查文件");
			}
			hsamap.put(userExcel.getCertificateType(),certificateType);
		}

		data.forEach(o -> {
			CertificateTypeEntity certificateType = hsamap.get(o.getCertificateType());
			CertificateTempEntity certificateTemp = new CertificateTempEntity();
			User result = UserCache.getUser(bladeUser.getTenantId(), o.getAccount());
			if (Func.isEmpty(result)) {
				User user = BeanUtil.copy(o, User.class);
				user.setTenantId(bladeUser.getTenantId());
				String deptIds = SysCache.getDeptIds(bladeUser.getTenantId(), o.getParentCompany());
				if(Func.isEmpty(deptIds)){
					user.setDeptId(bladeUser.getDeptId());

				}else {
					user.setDeptId(deptIds);

				}

				user.setPassword("zbh" + o.getAccount());
				user.setPhone(o.getAccount());
				String roleName = ParamCache.getValue("exhibitionUser" + certificateType.getBizDictKey());
				if (Func.isNotEmpty(roleName)) {
					user.setRoleId(SysCache.getRoleIds(bladeUser.getTenantId(), roleName));
				}
				user.setUserType(1);
				user.setRealName(o.getCompany());
				userClient.saveUser(user);
				log.info("创建用户:{}", user);
			} else {
				tempService.remove(Wrappers.<CertificateTempEntity>query().lambda().eq(CertificateTempEntity::getUserId, result.getId()).eq(CertificateTempEntity::getTypeName, o.getCertificateType()));
			}
			User user1 = UserCache.getUser(bladeUser.getTenantId(), o.getAccount());

			certificateTemp.setUserId(user1.getId());
			certificateTemp.setCertificateTypeId(certificateType.getId());
			certificateTemp.setMaxValu(o.getMaxValu());
			certificateTemp.setRealName(user1.getRealName());
			certificateTemp.setBizCode(certificateType.getBizCode());
			certificateTemp.setTypeName(o.getCertificateType());
			certificateTemp.setTypeKey(certificateType.getTypeKey());
			certificateTemp.setCreateDept(Long.parseLong(user1.getDeptId()));
			saveList.add(certificateTemp);
		});
		tempService.saveBatch(saveList);
	}
}
